/*
 * These files are distributed under the terms of the GNU GPLv2, the GNU General
 * Public version 2. See LICENSE.txt
 */
package fileCommodore.plugin.launcher;

import java.awt.event.*;
import java.io.*;
import java.util.*;

import javax.swing.*;

import fileCommodore.model.*;
import fileCommodore.plugin.*;

public class LauncherPlugin extends Plugin
{
	/*
	 * (non-Javadoc)
	 * 
	 * @see plugin.Plugin#activeSelectionChanged()
	 */
	@Override
	public void activeSelectionChanged()
	{
		// TODO Auto-generated method stub
		
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see plugin.Plugin#handle(java.awt.event.KeyEvent)
	 */
	@Override
	public void handle( KeyEvent ev )
	{
		if (( KeyEvent.VK_F11 == ev.getKeyCode() )
				|| ( KeyEvent.VK_R == ev.getKeyCode() && isAltDown( ev ) ))
		{
			String cmd =
					JOptionPane.showInputDialog(
						getDialogParent(),
						"Command to Run",
						"Please enter the command to run" );
			
			if (null != cmd && cmd.length()>0)
			{
				boolean useShell = !ev.isShiftDown();
				String[] command = cmd.split( "\\s" );
				File currentDir =
						new File(
								getActiveSelection().getCurrent().getFileObject().getName().getPath() );
				
				substituteAndLaunch( currentDir, command, useShell );
			}
		}
	}
	
	private String pathOf( FileRowItem fri )
	{
		String retval = fri.toFile().getAbsolutePath();
		return retval;
	}
	
	private void launch( File working, String[] args, boolean useShell )
	{
		try
		{
			if (useShell)
			{
				launchProcessWithTerminal( working, args, true );
			}
			else
			{
				launchProcessWithoutTerminal( working, args );
			}
		}
		catch (IOException e)
		{
			report( "Could not open DOS shell.", e );
		}
	}
	
	private void substituteAndLaunch( File startup, String[] in,
		boolean useShell )
	{
		ArrayList<String> al = new ArrayList<String>();
		ArrayList<Boolean> subed = new ArrayList<Boolean>();
		for (String s : in)
		{
			al.add( s );
			subed.add( false );
		}
		
		String s = pathOf( getActiveSelection().getSelected() );
		String d = pathOf( getActiveSelection().getCurrent() );
		
		String S = pathOf( getInactiveSelection().getSelected() );
		String D = pathOf( getInactiveSelection().getCurrent() );
		
		boolean has_t = false;
		boolean has_T = false;
		
		// Substitute %s, %S, %d and %D and check for @@t and @@T
		for (int i = 0; i < al.size(); i++)
		{
			subed.set( i, true );
			String v = al.get( i );
			if ("%s".equals( v ))
			{
				al.set( i, s );
			}
			else if ("%S".equals( v ))
			{
				al.set( i, S );
			}
			else if ("%d".equals( v ))
			{
				al.set( i, d );
			}
			else if ("%D".equals( v ))
			{
				al.set( i, D );
			}
			else
			{
				if ("@t".equals( v ))
				{
					has_t = true;
				}
				else if ("@T".equals( v ))
				{
					has_T = true;
				}
				subed.set( i, false );
			}
		}
		
		// Substitute %t and %T
		for (int i = al.size() - 1; i >= 0; i--)
		// Done backwards to avoid shuffling indices as we insert elements
		{
			if (!subed.get( i ))
			{
				Vector<FileRowItem> tagged = null;
				String v = al.get( i );
				
				if ("%t".equals( v ))
				{
					tagged = getActiveSelection().getTagged();
				}
				else if ("%T".equals( v ))
				{
					
					tagged = getInactiveSelection().getTagged();
				}
				
				if (null != tagged)
				{
					al.remove( i );
					subed.remove( i );
					
					// We'll always insert at the head
					Collections.reverse( tagged );
					
					for (FileRowItem fri : tagged)
					{
						al.add( i, pathOf( fri ) );
						subed.add( i, true );
					}
				}
			}
		}
		
		String[] args = new String[] {};
		args = al.toArray( args );
		
		if (has_t && has_T)
		{
			for (FileRowItem t : getActiveSelection().getTagged())
			{
				for (FileRowItem T : getInactiveSelection().getTagged())
				{
					String[] tmpArgs = subTag( t, T, args, subed );
					launch( startup, tmpArgs, useShell );
				}
			}
		}
		else if (has_t)
		{
			for (FileRowItem t : getActiveSelection().getTagged())
			{
				String[] tmpArgs = subTag( t, null, args, subed );
				launch( startup, tmpArgs, useShell );
			}
		}
		else if (has_T)
		{
			for (FileRowItem T : getInactiveSelection().getTagged())
			{
				String[] tmpArgs = subTag( null, T, args, subed );
				launch( startup, tmpArgs, useShell );
			}
		}
		else
		{
			launch( startup, args, useShell );
		}
	}
	
	private String[] subTag( FileRowItem t, FileRowItem T, String[] in,
		ArrayList<Boolean> subed )
	{
		String[] retval = new String[in.length];
		
		for (int i = 0; i < in.length; i++)
		{
			if ("@t".equals( in[i] ) && !subed.get( i ))
			{
				retval[i] = pathOf( t );
			}
			else if ("@T".equals( in[i] ) && !subed.get( i ))
			{
				retval[i] = pathOf( T );
			}
			else
			{
				retval[i] = in[i];
			}
		}
		
		return retval;
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see plugin.Plugin#inactiveSelectionChanged()
	 */
	@Override
	public void inactiveSelectionChanged()
	{
		// TODO Auto-generated method stub
		
	}
}
